package com.zyplayer.doc.git.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class DocUtil {

    protected static final Logger logger = LoggerFactory.getLogger(DocUtil.class);

    private static final List<String> defaultBlacklist = Lists.newArrayList(".nojekyll", "_navbar.md", "_sidebar.md", "index.html",
            "README.md", ".git");


    /**
     * @param docRootPath     docsify的根路径
     * @param sidebarFilePath _sidebar.md文件的绝对路径
     * @param fileFilterlist  不写入_sidebar.md文件 的文件名称
     */
    public static void autoGeneratorSidebarDir(String docRootPath, String sidebarFilePath, List<String> fileFilterlist) {
        if (CollectionUtil.isEmpty(fileFilterlist)) {
            fileFilterlist = defaultBlacklist;
        }
        logger.info("_sidebar文件根目录：{}", docRootPath);
        logger.info("_sidebar文件全路径：{}", sidebarFilePath);
        logger.info("文件黑名单：{}", JSONUtil.toJsonStr(fileFilterlist));
        List<String> resDirList = new ArrayList<>();
        File docRootDir = new File(docRootPath);
        if (!docRootDir.exists()) {
            throw new RuntimeException("路径不存在 " + docRootPath);
        }
        // dirFormat 侧边栏目录格式
        String dirFormat = "- [{0}]({1})";
        List<String> dirListTmp = new ArrayList<>();
        breadthTraversal(docRootDir, docRootPath, fileFilterlist, dirListTmp);
        logger.info("md文件整理结果：{}", JSONUtil.toJsonStr(dirListTmp));
        for (String e : dirListTmp) {
            //过滤不是md文件
            if (!e.endsWith(".md")) {
                continue;
            }
            int prefixIndex = e.lastIndexOf(File.separator) + 1;
            String dirName = e.substring(Math.max(prefixIndex, 0), e.indexOf("."));
            resDirList.add(MessageFormat.format(dirFormat, dirName, e));
        }
        //默认排序
        resDirList = resDirList.stream().sorted().collect(Collectors.toList());
        logger.info("_sidebar目录名称：{}", JSONUtil.toJsonStr(resDirList));
        File destFile = new File(sidebarFilePath);

        try {
            OutputStream os = new FileOutputStream(destFile, false);
            OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8);
            BufferedWriter bWriter = new BufferedWriter(writer);
            resDirList.forEach(e -> {
                try {
                    bWriter.write(e);
                    bWriter.newLine();
                } catch (IOException e1) {
                    logger.info("写入文件 {} 失败 {}", sidebarFilePath, e1.getMessage());
                }
            });
            bWriter.close();
        } catch (IOException e1) {
            logger.info("输出流异常 {}", e1.getMessage());
        }

    }

    private static void breadthTraversal(File file, String parentDirStr, List<String> fileFilterlist,
                                         List<String> resDirList) {
        if (file.isHidden()) {
            return;
        }
        if (file.isFile()) {
            try {
                String canonicalPath = file.getCanonicalPath();
                String needReplacePath = PathUtils.checkPathEndIsSlash(parentDirStr);
                logger.info("needReplacePath:{}", needReplacePath);
                String dir = canonicalPath
                        .replace(needReplacePath, "");
                resDirList.add(dir);
            } catch (IOException e) {
                System.out.println("无效文件：" + e.getMessage());
            }
            return;
        }
        FileFilter fileFilter = new FileFilter() {

            @Override
            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                }
                String name = f.getName();
                return !fileFilterlist.contains(name);
            }

        };
        File[] listFiles = file.listFiles(fileFilter);
        if (listFiles == null) {
            return;
        }
        for (File f : listFiles) {
            breadthTraversal(f, parentDirStr, fileFilterlist, resDirList);
        }


    }
}
